//
//  SFCClient.h
//  SVNForCocoa
//
//  Created by Jeremy Pereira on 07/11/2013.
//  Copyright (c) 2013 Jeremy Pereira. All rights reserved.
//
/*!
 *    @file
 *    @brief Declarations associated with an svn client.
 */

#import <Foundation/Foundation.h>
#import "SFCObject.h"
#import "SFCClientTypes.h"

@class SFCRevision;
@class SFCLock;

@protocol SFCAuthenticationProvider;

/*!
 *    @brief Object containing commit info for a successful commit.
 */
@interface SFCCommitInfo : SFCObject

/*!
 *    @brief Revision number associated with the commit.
 */
@property (nonatomic, readonly, assign) SFCRevNum revision;

/*!
 *    @brief Date of the commit.
 *
 *    @todo Make it an NSDate
 */
@property (nonatomic, readonly, copy) NSString* date;
/*!
 *    @brief Author of the commit.
 */
@property (nonatomic, readonly, copy) NSString* author;
/*!
 *    @brief Error message from post commit if there is one.
 */
@property (nonatomic, readonly, copy) NSString* postCommitError;
/*!
 *    @brief Repository root.
 *
 *    @todo maybe make it an NSURL
 */
@property (nonatomic, readonly, copy) NSString* repositoryRoot;

@end


/*!
 *    @brief Info structure about a working copy.
 */
@interface SFCWorkingCopyInfo :  SFCObject

@end

/*!
 *    @brief Info object for when the info of an item is requested.
 *    @todo Properly document the properties.
 */
@interface SFCClientInfo : SFCObject

@property (nonatomic, readonly, copy) NSURL* URL;
@property (nonatomic, readonly, assign) SFCRevNum revision;
@property (nonatomic, readonly, copy) NSURL* repositoryRoot;
@property (nonatomic, readonly, copy) NSString* UUID;
@property (nonatomic, readonly, assign) SFCNodeKind kind;
@property (nonatomic, readonly, assign) size_t fileSize;
@property (nonatomic, readonly, assign) SFCRevNum lastChangedRevision;
@property (nonatomic, readonly, copy) NSDate* lastChangedDate;
@property (nonatomic, readonly, copy) NSString* lastChangedAuthor;
@property (nonatomic, readonly, strong) SFCLock* lock;
@property (nonatomic, readonly, strong) SFCWorkingCopyInfo* workingCopyInfo;

@end

/*!
 *    @brief An object that describes a log change path in a Log entry
 *    @todo Remaining properties
 *    @todo Document properly
 */
@interface SFCLogChangedPath : SFCObject

@property (nonatomic, readonly, assign) SFCNodeKind kind;
@property (nonatomic, readonly, assign) SFCLCPAction action;
@property (nonatomic, readonly, copy) NSString* copiedFromPath;
@property (nonatomic, readonly, assign) SFCRevNum copiedFromRevision;

@end

/*!
 *    @brief Object containing information about a specific revision log.
 */
@interface SFCLogEntry : SFCObject

/*!
 *    @brief Revision number associated with the commit.
 */
@property (nonatomic, readonly, assign) SFCRevNum revision;

/*!
 *    @brief Does the log entry have children
 */
@property (nonatomic, readonly, assign) bool hasChildren;
/*!
 *    @brief Is the revision non inheritable
 */
@property (nonatomic, readonly, assign) bool nonInheritable;
/*!
 *    @brief Is the revision a subtractive merge e.g. a reverse merge.
 */
@property (nonatomic, readonly, assign) bool subtractiveMerge;

/*!
 *    @brief Revision properties set in the log entry.
 *
 *    Note that this might not be an exhaustive list if not all rev props were
 *    asked for.
 */
@property (nonatomic, readonly, strong) NSDictionary* revisionProperties;

/*!
 *    @brief Changed paths in the revision represented by the log entry.
 */
@property (nonatomic, readonly, strong) NSDictionary* changedPaths;

@end

/*!
 *    @brief Object describing a status entry during a status:... invocation.
 *    @todo Document all the properties.
 */
@interface SFCStatusEntry : SFCObject
/*!
 *    @brief Kind of node (file, directory etc)
 */
@property (nonatomic, readonly, assign) SFCNodeKind kind;
/*!
 *    @brief Absolute path of the local copy of the node.
 */
@property (nonatomic, readonly, copy) NSString* localAbsolutePath;
/*!
 *    @brief Size of the file in bytes.
 */
@property (nonatomic, readonly, assign) uint64_t fileSize;
/*!
 *    @brief True if the node is under version control.
 */
@property (nonatomic, readonly, assign) bool isVersioned;
/*!
 *    @brief True if the node is in a conflicted state.
 */
@property (nonatomic, readonly, assign) bool isConflicted;
/*!
 *    @brief Commit status of the node.
 */
@property (nonatomic, readonly, assign) SFCWCStatusKind nodeStatus;
/*!
 *    @brief Commit status of the propoerties of the node.
 */
@property (nonatomic, readonly, assign) SFCWCStatusKind propertyStatus;
/*!
 *    @brief True if the node is locked.
 */
@property (nonatomic, readonly, assign) bool isLocked;
/*!
 *    @brief True if the node is copied,
 */
@property (nonatomic, readonly, assign) bool isCopied;
/*!
 *    @brief Repository root
 *
 *    @todo Probably should be a NSURL.
 *    @todo Might still need the backwards compat. baton
 */
@property (nonatomic, readonly, copy) NSString* repositoryRootURL;
/*!
 *    @brief Repositoy's unique id.
 */
@property (nonatomic, readonly, copy) NSString* repositoryUUID;
/*!
 *    @brief Path of the node relative to the repository root.
 */
@property (nonatomic, readonly, copy) NSString* repositoryRelativePath;
@property (nonatomic, readonly, assign) SFCRevNum revision;
@property (nonatomic, readonly, assign) SFCRevNum changedRevision;
@property (nonatomic, readonly, copy) NSDate* changedDate;
@property (nonatomic, readonly, copy) NSString* changedAuthor;
@property (nonatomic, readonly, assign) bool isSwitched;
@property (nonatomic, readonly, assign) bool isExternal;
@property (nonatomic, readonly, strong) SFCLock* lock;
@property (nonatomic, readonly, copy) NSString* changeList;
@property (nonatomic, readonly, assign) SFCDepth depth;
@property (nonatomic, readonly, assign) SFCNodeKind outOfDateKind;
@property (nonatomic, readonly, assign) SFCWCStatusKind repositoryPropertyStatus;
@property (nonatomic, readonly, strong) SFCLock* repositoryLock;
@property (nonatomic, readonly, assign) SFCRevNum outOfDateChangedRevision;
@property (nonatomic, readonly, copy) NSDate* outOfDateChangedDate;
@property (nonatomic, readonly, copy) NSString* outOfDateChangedAuthor;
@property (nonatomic, readonly, copy) NSString* movedFromAbsPath;
@property (nonatomic, readonly, copy) NSString* movedToAbsPath;

@end

/*!
 *    @brief A directory entry for list operations.
 *
 *    Contains information about a node as used in a list operation.
 */
@interface SFCDirectoryEntry : SFCObject
/*!
 *    @brief The kind of node to which this object refers.
 */
@property (nonatomic, readonly, assign) SFCNodeKind kind;
/*!
 *    @brief The size of the file.
 *
 *    This will be 0 if the node is a directory.
 */
@property (nonatomic, readonly, assign) size_t fileSize;
/*!
 *    @brief True if the node has properties.
 */
@property (nonatomic, readonly, assign) bool hasProperties;
/*!
 *    @brief The revision in which this node was created.
 */
@property (nonatomic, readonly, assign) SFCRevNum createdRevision;
/*!
 *    @brief Time stamp of the created revision.
 */
@property (nonatomic, readonly, copy) NSDate* createdDate;
/*!
 *    @brief Author of the created revision.
 */
@property (nonatomic, readonly, copy) NSString* lastAuthor;

@end

/*!
 *    @brief Notification object for client notifications.
 *    @todo Put some data in.
 */
@interface SFCWCNotification : SFCObject

@end

/*!
 *    @brief Information about an inherited property.
 */
@interface SFCPropertyInheritedItem : SFCObject

/*!
 *    @brief The path or URL of the target node.
 */
@property (readonly, copy) NSString* pathOrURL;

/*!
 *    @brief A dictionary of inherited proerty names and values for the node.
 */
@property (readonly, strong) NSDictionary* properties;

@end

/*!
 *    @brief Options to set for a diff.
 */
@interface SFCDiffOptions : SFCObject
/*!
 *    @brief Return us a set of default diff options.
 *
 *    @return The default diff options.
 */
+(SFCDiffOptions*) defaultOptions;
/*!
 *    @brief Return as some diff options with the given options.
 *
 *    @param ignoreSpace    How far do we go to ignore spaces, see 
 *                          SFCDiffFileIgnoreSpace
 *    @param eolStyle       Do we ignore different end of lines.
 *    @param showCFunctions Do we show C functions in the @@ line.
 *
 *    @return A new SFCDiffOptions.
 */
+(SFCDiffOptions*) ignoreSpace: (SFCDiffFileIgnoreSpace) ignoreSpace
                ignoreEOLStyle: (bool) eolStyle
                showCFunctions: (bool) showCFunctions;
/*!
 *    @brief The extent to which we ignore spaces.
 */
@property (nonatomic, readonly, assign) SFCDiffFileIgnoreSpace ignoreSpace;
/*!
 *    @brief Do we ignore differences in line ending.
 */
@property (nonatomic, readonly, assign) bool ignoreEOLStyle;
/*!
 *    @brief Should the @@ block make an attempt at showing the C function.
 */
@property (nonatomic, readonly, assign) bool showCFunction;

@end

@interface SFCVersion : SFCObject

@property (nonatomic, readonly, assign) int frameworkMajorVersion;
@property (nonatomic, readonly, assign) int svnMajorVersion;
@property (nonatomic, readonly, assign) int svnMinorVersion;
@property (nonatomic, readonly, assign) int svnPatchVersion;
@property (nonatomic, readonly, copy) NSString* svnTag;

@end

/*!
 *    @brief A copy source object.
 *
 *    This is a file at a particular revision as defined by the peg revision.
 */
@interface SFCClientCopySource : SFCObject

/*!
 *    @brief Create a SFCClientCopySource
 *
 *    @param path        The path or URL of the file
 *    @param pegRevision The peg revision of the path, if unspecified, use head.
 *    @param revision    The revision of the path.
 *
 *    @return a SFCClientCopySource
 */
+(SFCClientCopySource*) sourceFromPath: (NSString*) path
                           pegRevision: (SFCRevision*) pegRevision
                    		  revision: (SFCRevision*) revision;

/*!
 *    @brief Get a client copy source from the working copy.
 *
 *    @param path Path, which must be a wc path.
 *
 *    @return A client copy source.
 */
+(SFCClientCopySource*) sourceFromWorkingCopyPath: (NSString*) path;

@property (nonatomic, readonly, copy) NSString* path;
@property (nonatomic, readonly, copy) SFCRevision* pegRevision;
@property (nonatomic, readonly, copy) SFCRevision* revision;

@end

/*!
 *    @brief A normal file sytem directory entry.
 *
 *    This differs from SFCDirectoryEntry in that it refers to unversioned files
 *    on the file system.
 *    @todo Fill in some details.
 */
@interface SFCIODirectoryEntry : SFCObject

/*!
 *    @brief The kind of node to which this object refers.
 */
@property (nonatomic, readonly, assign) SFCNodeKind kind;
/*!
 *    @brief The size of the file.
 *
 *    This will be 0 if the node is a directory.
 */
@property (nonatomic, readonly, assign) size_t fileSize;

/*!
 *    @brief true if this is a special file e.g. device
 */
@property (nonatomic, readonly, assign) bool isSpecial;

/*!
 *    @brief Modification time of the file.
 */
@property (nonatomic, readonly, copy) NSDate* modificationTime;

@end

/*!
 *    @brief Information about one of the conflicting versions of the node.
 *
 *    Note that not all of the properties need to be set with a value, if the
 *    relevant information is not present.
 */
@interface SFCConflictVersion : SFCObject

/*!
 *    @brief The node kind.
 */
@property (nonatomic, readonly, assign) SFCNodeKind nodeKind;
@property (nonatomic, readonly, copy) NSString* uuid;
@property (nonatomic, readonly, copy) NSURL* repositoryURI;
@property (nonatomic, readonly, assign) SFCRevNum pegRevision;
@property (nonatomic, readonly, copy) NSString* pathInRepository;

@end

/*!
 *    @brief Describes a conflict that needs resolving.
 */
@interface SFCConflictDescription : SFCObject
/*!
 *    @brief The path in conflict.
 */
@property (nonatomic, readonly, copy) NSString* localAbsPath;
/*!
 *    @brief The node kind.
 */
@property (nonatomic, readonly, assign) SFCNodeKind nodeKind;
/*!
 *    @brief Kind of conflict.
 */
@property (nonatomic, readonly, assign) SFCConflictKind conflictKind;

@property (nonatomic, readonly, copy) NSString* propertyName;
@property (nonatomic, readonly, assign) bool isBinary;
@property (nonatomic, readonly, copy) NSString* mimeType;
@property (nonatomic, readonly, assign) SFCConflictAction confictAction;
@property (nonatomic, readonly, assign) SFCConflictReason conflictReason;
@property (nonatomic, readonly, copy) NSString* baseAbsPath;
@property (nonatomic, readonly, copy) NSString* theirAbsPath;
@property (nonatomic, readonly, copy) NSString* myAbsPath;
@property (nonatomic, readonly, copy) NSString* mergedFile;
@property (nonatomic, readonly, assign) SFCOperation operation;
@property (nonatomic, readonly, copy) SFCConflictVersion* sourceLeftVersion;
@property (nonatomic, readonly, copy) SFCConflictVersion* sourceRightVersion;

@end
/*!
 *    @brief Encapsulates a conflict resolution decision.
 */
@interface SFCConflictResult : SFCObject

@property (nonatomic, readonly, assign) SFCConflictChoice choice;
@property (nonatomic, readonly, copy) NSString* mergedFile;
@property (nonatomic, readonly, assign) bool saveMerged;

/*!
 *    @brief DEsignanted initialiser
 *
 *    @param choice     How the conflict was resolved.
 *    @param mergedFile A file containing a merged version of the node.
 *    @param saveMerged true to save a backup of the merged file.
 *
 *    @return A conflict resolution result
 */
-(id) initWithChoice: (SFCConflictChoice) choice
          mergedFile: (NSString*) mergedFile
          saveMerged: (bool) saveMerged;

@end

/*!
 *    @brief Abstracts a client to subversion.
 *
 *    Roughly speaking this wraps an @c svn_client_ctx_t.
 *    @todo +aprArrayOfRevisionRangesFrom:wihPool needs to allocate the ranges
 *          from the pool.
 *    @todo Initialise with an empty set of authentication providers to stop
 *          the bad access on the null pointer.
 *    @todo Test the conflictBlock version of resolve
 */
@interface SFCClient : SFCObject

/*!
 *    @brief Designated initialiser.
 *
 *    This initialises a new SFCClient.  If anything goes wrong, the error will
 *    be filled in.
 *
 *    -init just calls this with a nil error.
 *
 *    @param error If something goes wrong, this will be filled in.
 *
 *    @return A new SFCClient.
 */
-(id) initWithError: (NSError* __autoreleasing*) error;

/*!
 *    @brief Version information for this client.
 *
 *    @return version information.
 */
+(SFCVersion*) version;

/*!
 *    @brief Block to call during various poperations at various points.
 */
@property (nonatomic, copy) SFCClientNotifyBlock notifyBlock;

/*!
 *    @brief A block that is used to get commit log messages when required.
 */
@property (nonatomic, copy) SFCGetCommitLog commitLogBlock;

/*!
 *    @brief Comfict resolution block.
 *
 *    can be called during updates, resolves and merges to resolve conflicts
 *    interactively.
 */
@property (nonatomic, copy) SFCConfictResolverBlock conflictResolver;

/*!
 *    @brief Get a status string for the numeric status
 *
 *    @param numericStatus Status to convert to string.
 *
 *    @return String version of status - use same values as an svn status.
 */
+(NSString*) stringForStatus: (SFCWCStatusKind) numericStatus;

/*!
 *    @brief Adds an authentication provider to the list of auth providers.
 *
 *    Providers are tried in the order that they are added.
 *
 *    @param newProvider The new provider to add.
 */
-(void) addAuthenticationProvider: (id<SFCAuthenticationProvider>) newProvider;
/*!
 *    @brief Checkout a working copy.
 *
 *    @param[in] url              Repository URL to check out.
 *    @param[in] path             Local path to put the working copy in.
 *    @param[in] pegRevision      Peg revision for checkout, if nil, assume no peg
 *                                revision has been specified i.e. HEAD.
 *    @param[in] revision         Revision to check out, if nil, assume no
 *                                revision has been specified i.e. HEAD.
 *    @param[in] depth            Depth of checkout, if nil assume infinity.
 *    @param[in] ignoreExternals  If true, do not checkout externals.
 *    @param[in] allowUnversionedObstructions If true then tolerate existing
 *                                            unversioend items that obstruct
 *                                            incoming paths.
 *    @param[out] resultRevision  If non NULL, the actual revision checked out goes
 *                                in here.
 *    @param[out] error           If an error occurs and this is non null, it
 *                                will be filled in with an error.
 *
 *    @return true if the working copy was checked out successfully.
 */
-(bool) checkoutURL: (NSURL*) url
               path: (NSString*) path
        pegRevision: (SFCRevision*) pegRevision
           revision: (SFCRevision*) revision
              depth: (SFCDepth) depth
    ignoreExternals: (bool) ignoreExternals
allowUnversionedObstructions: (bool) allowUnversionedObstructions
     resultRevision: (SFCRevNum*) resultRevision
              error: (NSError* __autoreleasing*) error;

/*!
 *    @brief Commit aset of objects in a working copy.
 *
 *    This method commits a set of files and/or directories.
 *
 *    @param targets        List of paths to commit targets.
 *    @param depth          Depth of commit, see SFCDepth for more info.
 *    @param options        Options for the commit, see SFCCommitOptions for
 *                          details.  Multiple options may be specified by 
 *                          using a bitwise or.
 *    @param changeLists    List of changelists to filter targets on.  This can
 *                          be empty or NULL, in which case no filtering occurs.
 *    @param revPropTable   Revision properties included in the commit.  This
 *                          can be NULL.
 *    @param committedBlock A block that is called for each successful commit.
 *    @param error          If an error occurs and this is non NULL, it will be
 *                          filled in with the error details.
 *
 *    @return true if the commit is sucessful.
 */
-(bool) commit: (NSArray*) targets
         depth: (SFCDepth) depth
       options: (uint32_t) options
    changLists: (NSArray*) changeLists
  revPropTable: (NSDictionary*) revPropTable
committedBlock: (SFCCommittedBlock) committedBlock
         error: (NSError* __autoreleasing*) error;

/*!
 *    @brief Do an svn log.
 *
 *    Finds all the logs associated with all of the targets.  The block is 
 *    invoked once per log record.
 *
 *    @param targets        Either a URI followed by zero or more relative 
 *                          paths or a single path in a working copy.
 *    @param pegRevision    The peg revision if any.  Nil means head.
 *    @param revisionRanges A list of revision ranges for which to get logs.
 *    @param limit          If non zero, only the first limit logs will be 
 *                          processed.
 *    @param options        Various options.  See SFCLogOptions for details.
 *    @param revPropTable   Revision properties included in the commit.  This
 *                          can be nil and if it is, all revision properties
 *                          will be retrieved.
 *    @param logBlock       Block to invoke once for each log.
 *    @param error			If an error occurs and this is non null, it will be
 *                          filled in with error information.
 *
 *    @return true if the log completed successfully.
 */
-(bool)    log: (NSArray*) target
   pegRevision: (SFCRevision*) pegRevision
revisionRanges: (NSArray*) revisionRanges
         limit: (int) limit
       options: (uint32_t) options
  revPropTable: (NSArray*) revPropTable
      logBlock: (SFCLogBlock) logBlock
         error: (NSError* __autoreleasing*) error;

/*!
 *    @brief Performs a status operation on the given path.
 *
 *    For each status entry, the statusBlock is invoked.  If 
 *    SFC_STATUS_OPTION_UPDATE is set, the server is contacted for update
 *    information.
 *
 *    @param path           Path to find status on which must be in a working
 *                          copy.
 *    @param revision       Revision to decide whrther wc is out of date
 *    @param depth          Depth of status, see SFCDepth for more info
 *    @param options        Various status options, see SFCStatusOptions for
 *                          more info.
 *    @param changeLists    Array of change list names to use as a filter.
 *    @param statusBlock    Block to execute for each status line.
 *    @param resultRevision Revision in the repo against which the wc was
 *                          checked if SFC_STATUS_OPTION_UPDATE is set.  NULL
 *                          may be passed, if you are not interested.
 *    @param error          If an error occurs and this is non null, it will
 *                          be filled in with error details.
 *
 *    @return true if the tatus works OK
 */
-(bool) status: (NSString*) path
      revision: (SFCRevision*) revision
         depth: (SFCDepth) depth
       options: (uint32_t) options
   changeLists: (NSArray*) changeLists
   statusBlock: (SFCStatusBlock) statusBlock
resultRevision: (SFCRevNum*) resultRevision
         error: (NSError* __autoreleasing*) error;

/*!
 *    @brief Do an update on the given paths
 *
 *    @param paths           Array of paths to update
 *    @param revision        Revision to update to, if nil, HEAD is assumed.
 *    @param depth           if SFC_DEPTH_INFINITY, update fully recursively. 
 *                           Else if it is SFC_DEPTH_IMMEDIATES or 
 *                           SFC_DEPTH_FILES, update each target and its file 
 *                           entries, but not its subdirectories. Else if 
 *                           SFC_DEPTH_EMPTY, update exactly each target, 
 *                           nonrecursively (essentially, update the target's 
 *                           properties).
 *    @param options         Various update options, see SFCUpdateOptions for 
 *                           details.
 *    @param resultRevisions If not NULL, this will be filled in with an array 
 *                           containing revision numbers for the corresponding 
 *                           paths.
 *    @param error           If non null and an error occurs, this will be 
 *                           filled in with the error.
 *
 *    @return True if the update is successful.
 */
-(bool) update: (NSArray*) paths
      revision: (SFCRevision*) revision
         depth: (SFCDepth) depth
       options: (uint32_t) options
resultRevisions: (NSArray* __autoreleasing*) resultRevisions
         error: (NSError* __autoreleasing*) error;

/*!
 *    @brief Add a file system object to the working copy.
 *
 *    This schedules a file or folder for addition to the repository on the 
 *    next commit.
 *
 *    @param path    Path to file system object to add.
 *    @param depth   Controls the depth of the addition e.g. the whole tree or
 *                   just the top level.
 *    @param options Various add options, see SFCAddOptions for details.
 *    @param error   If non null and an error occurs, this will be filled in 
 *                   with the error.
 *
 *    @return true if the add was successful, error otherwise.
 */
-(bool) add: (NSString*) path
      depth: (SFCDepth) depth
    options: (uint32_t) options
      error: (NSError* __autoreleasing*) error;

/*!
 *    @brief Revert a selection of paths.
 *
 *    If a path in paths is a file, it is reverted to the working copy base.  If
 *    it is a directory, it is reverted according to the supplied depth.
 *
 *    @param paths       List of paths as strings to revert.
 *    @param depth       Depth to revert to.
 *    @param changeLists Change list to filter paths by.
 *    @param error       If non nil and there is an error, this is filled in 
 *                       with the details.
 *
 *    @return True if no error occurs.
 */
-(bool) revert: (NSArray*) paths
         depth: (SFCDepth) depth
   changeLists: (NSArray*) changeLists
         error: (NSError* __autoreleasing*) error;
/*!
 *    @brief Get info about a path in a working copy.
 *
 *    This method performs an info on the given path.  Note that, as the path is
 *    passed unchanged apart from coversion to UTF-8 to the underlying client 
 *    function, it will also work if the string happens to be the URL of a 
 *    repository object.
 *
 *    @param path            Path of thing to get the info of.
 *    @param pegRevision     Peg revision for info operation, if this and 
 *                           revision are nil or unspecified, the info will be 
 *                           pulled from the working copy.
 *    @param revision        Revision to look at.
 *    @param depth           If the path is a directory this specifies how far
 *                           down the tree to go.
 *    @param fetchExcluded   If true, fetch nodes excluded from the working
 *                           copy.
 *    @param fetchActualOnly If true, fetch nodes that don't exist as versioned 
 *                           but are conficted.
 *    @param changeLists     Filter the results on the change list, if empty or 
 *                           nil, no filtering occurs.
 *    @param infoBlock       Block to execiute for each item about which we get
 *                           some information.  It takes a path parameter and an
 *                           info object.  If you return false, you must fill in
 *                           the error parameter.
 *    @param error           If an error occurs and this is non nil, it will be 
 *                           filled in with an error.
 *
 *    @return true if the info works.
 */
-(bool) infoPath: (NSString*) path
     pegRevision: (SFCRevision*) pegRevision
        revision: (SFCRevision*) revision
           depth: (SFCDepth) depth
   fetchExcluded: (bool) fetchExcluded
 fetchActualOnly: (bool) fetchActualOnly
     changeLists: (NSArray*) changeLists
       infoBlock: (bool (^)(NSString* path, SFCClientInfo* info, NSError* __autoreleasing* error)) infoBlock
           error: (NSError* __autoreleasing*) error;

/*!
 *    @brief Run an svn mkdir.
 *
 *    Makes a directory at each of the given working copy paths or repository
 *    URLs.
 *
 *    @param paths              Set of paths in the working copy or URLs in the
 *                              repository to make directories of.
 *    @param makeParents        Makes any non existing parent directories.
 *    @param revisionProperties Revision properties to set for repo URLs.
 *    @param committedBlock     A block that is called for each successful
 *                              commit.
 *    @param error              Filled in if there is an error and is non nil.
 *
 *    @return true for success, false for an error.
 */
-(bool)      mkDir: (NSArray*) paths
       makeParents: (bool) makeParents
revisionProperties: (NSDictionary*) revisionProperties
    committedBlock: (SFCCommittedBlock) committedBlock
             error: (NSError* __autoreleasing*) error;

/*!
 *    @brief Lock a set of items in the repository or working copy.
 *
 *    There must be an authentication provider to supply a uer name.
 *
 *    @param paths     List of paths in a wc to lock or URLs in the repository.
 *    @param comment   A comment for the lock.
 *    @param stealLock If true, steal the lock if somebody else has it.
 *    @param error     Will be filled in if there is an error and non nil.
 *
 *    @return True if the lock was successful.
 */
-(bool) lock: (NSArray*) paths
     comment: (NSString*) comment
   stealLock: (bool) stealLock
       error: (NSError* __autoreleasing*) error;

/*!
 *    @brief Unlock a set of locked paths or URLs.
 *
 *    <#Description#>
 *
 *    @param paths     List of paths in a wc to unlock or URLs in the repository.
 *    @param breakLock If true will brweak locks that aren't owned by the 
 *                     authenticated user.
 *    @param error     Will be filled in if non nil and there is an error.
 *
 *    @return true if the unlock succeeded
 */
-(bool) unlock: (NSArray*) paths
   	 breakLock: (bool) breakLock
         error: (NSError* __autoreleasing*) error;

/*!
 *    @brief Diff two files or two revisions of a file.
 *
 *    This looks like a generalised diffing tool.  However, because we are 
 *    using @c svn_client_diff6(), we only have a restricted set of allowed use
 *    cases, these are:
 *    @li Compare @c wcpath\@BASE vs. @c wcpath\@WORKING
 *    @li Compare some @c URL\@REV vs. @c wcpath\@WORKING
 *    @li Compare some @c URL1\@REV1 vs. @c URL2\@REV2
 *
 *    Anything else causes  @c svn_client_diff6() to return an error.
 *
 *    @param diffOptions    Set of command line options that will be sent to an
 *                          external diff program.
 *    @param path1          Path of first file to diff, or a URL in the repo.
 *    @param revision1      Revision of first file to be diffed.
 *    @param path2          Path of second file to be diffed.  Must represent
 *                          the same kind of node (file or directory) as path1.
 *    @param revision2      Revision of second file to be diffed.
 *    @param relativeToDir  If relative_to_dir is not NULL, the original path 
 *                          and modified path will have the relative_to_dir 
 *                          stripped from the front of the respective paths. If 
 *                          relative_to_dir is NULL, paths will not be modified. 
 *                          If relative_to_dir is not NULL but relative_to_dir 
 *                          is not a parent path of the target, an error is 
 *                          returned. Finally, if relative_to_dir is a URL, an 
 *                          error will be returned.
 *    @param depth          For directories determins the depth of diffing.
 *    @param options        Various options, see SFCDiffOptions.
 *    @param headerEncoding Generated headers are encoded using headerEncoding.
 *                          This does not apply to external diff programs. Also
 *                          not all Cocoa string encodings are necessarily 
 *                          supported.
 *    @param outStream      Stream on which to write diff output.
 *    @param errorStream    Stream on which to write errors.  May be nil, in 
 *                          which case errors will be discarded.
 *    @param changeLists    Change lists to filter diff files on or nil.
 *    @param error          If an error occurs, this will be filled in.
 *
 *    @return true if the diff completes without error.
 */
-(bool) diffCmdOptions: (NSArray*) diffOptions
                 path1: (NSString*) path1
          	 revision1: (SFCRevision*) revision1
             	 path2: (NSString*) path2
         	 revision2: (SFCRevision*) revision2
     	 relativeToDir: (NSString*) relativeToDir
                 depth: (SFCDepth) depth
               options: (uint32_t) options
		headerEncoding: (NSStringEncoding) headerEncoding
   			 outStream: (NSOutputStream*) outStream
           errorStream: (NSOutputStream*) errorStream
           changeLists: (NSArray*) changeLists
       			 error: (NSError* __autoreleasing*) error;

/*!
 *    @brief Add the given list of paths to a change list.
 *
 *    If a path is already a member of another changelist, then remove it from 
 *    the other changelist and add it to changelist.
 *
 *    @param paths       PAths to add to the change list
 *    @param changeList  Name of change list to add paths to.
 *    @param depth       Depth filter
 *    @param changeLists Cjhangelist filter
 *    @param error       THis will be filled in if an error occurs.
 *
 *    @return true if the add is successful.
 */
-(bool) addPaths: (NSArray*) paths
    toChangeList: (NSString*) changeList
           depth: (SFCDepth) depth
     changeLists: (NSArray*) changeLists
           error: (NSError* __autoreleasing*) error;

/*!
 *    @brief Get a property of a target.
 *
 *    @param propertyName        The property we are going to get.
 *    @param target              The target - either a path or a URL represented
 *                               as a string.
 *    @param pegRevision         Peg revision to get property at (or nil)
 *    @param revision            Revision to get property at, if nil, head or 
 *                               working copy is assumed.
 *    @param depth               Tells us which actual nodes to get properties
 *                               from if the target is a directory.
 *    @param changeLists         Change list filter for target and depth.
 *    @param properties          Will be set to a NSDictionary keyed by absolute 
 *                               path unless it is nil.
 *    @param inheritedProperties If non nil, will be set to an array of 
 *                               SFCPropertyInheritedItem for target and its
 *                               ancestors.
 *    @param actualRevision      If non null, will be set to the actual revision
 *                               fetched.
 *    @param error               If non nil and an error occurs, will be set to 
 *                               the error.
 *
 *    @return true if command operates successfully.
 */
-(bool) propGet: (NSString*) propertyName
         target: (NSString*) target
    pegRevision: (SFCRevision*) pegRevision
       revision: (SFCRevision*) revision
          depth: (SFCDepth) depth
    changeLists: (NSArray*) changeLists
     properties: (NSDictionary* __autoreleasing*) properties
      inherited: (NSArray* __autoreleasing*) inheritedProperties
 actualRevision: (SFCRevNum*) actualRevision
          error: (NSError* __autoreleasing*) error;

/*!
 *    @brief Set a property on targets in a working copy.
 *
 *    @param propertyName Name of property to set.
 *    @param value        Value to set property to
 *    @param targets      Working copy paths on which to set properties
 *    @param depth        Depth for directory targets.
 *    @param skipChecks   If true, skip validity checks for the proerty value
 *    @param changeLists  Change list filter for targets
 *    @param error        If non nil, will be filled in with an error, if the 
 *                        method fails.
 *
 *    @return true for success, false otherwise.
 */
-(bool) propSet: (NSString*) propertyName
          value: (NSString*) value
      wcTargets: (NSArray*) targets
          depth: (SFCDepth) depth
     skipChecks: (bool) skipChecks
    changeLists: (NSArray*) changeLists
          error: (NSError* __autoreleasing*) error;

/*!
 *    @brief Set a property on a URL in a repository.
 *
 *    @param propertyName       Name of the property to set.
 *    @param value              Value of the proerty to set.
 *    @param target             Target URL
 *    @param depth              Depth for setting properties on directories.
 *    @param skipChecks         If true, skip validation checks for the property.
 *    @param baseRevisionForUrl If the property has changed on url since  
 *                              baseRevisionForUrl (which must not be 
 *                              SVN_INVALID_REVNUM), no change will be made and 
 *                              an error will be returned.
 *    @param revisionProperties If non-NULL, revisionProperties is a dictionary 
 *                              holding additional, custom revision properties 
 *                              to be set on the new revision. This table cannot 
 *                              contain any standard Subversion properties.
 *    @param commitBlock        If non null, is an SFCCommittedBlock called on 
 *                              the commit.
 *    @param error              If not nil and an error occurs, this will be 
 *                              filled in with error information.
 *
 *    @return true if the propset worked ok or false, otherwise.
 */
-(bool) propSet: (NSString*) propertyName
          value: (NSString*) value
     repoTarget: (NSURL*) target
          depth: (SFCDepth) depth
     skipChecks: (bool) skipChecks
       revision: (SFCRevNum) baseRevisionForUrl
revisionProperties: (NSDictionary*) revisionProperties
 committedBlock: (SFCCommittedBlock) commitBlock
          error: (NSError* __autoreleasing*) error;

/*!
 *    @brief Cat the content of the given path or URL to the supplied output 
 *           stream.
 *
 *    @param pathOrUrl   Path or URL to cat
 *    @param pegRevision Peg revision of path or URL
 *    @param revision    Revision of the path or URL
 *    @param stream      Output stream into which the file is catted.
 *    @param error       If non nil and there is an error, this will be filled in.
 *
 *    @return true if the cat works.
 */
-(bool) cat: (NSString*) pathOrUrl
pegRevision: (SFCRevision*) pegRevision
   revision: (SFCRevision*) revision
     stream: (NSOutputStream*) stream
      error: (NSError* __autoreleasing*) error;
/*!
 *    @brief Do an svn blame, each line causing an execution of the blameBlock
 *
 *    @param pathOrUrl              Item to execute blame on.
 *    @param pegRevision            Indicates in which revision path_or_url is
 *                                  valid.  If unspecified or nil, assume HEAD.
 *    @param start                  Start revision.  The default blame is the 
 *                                  author of this revision.
 *    @param end                    End revision.
 *    @param diffOptions            Options for diffing the files.
 *    @param ignoreMimeType         Blame is not generated for binary mime types
 *                                  unless this option is true.
 *    @param includeMergedRevisions also return data based upon revisions which 
 *                                  have been merged to path_or_url.
 *    @param blameBlock             Block invoked for each line of blame.
 *    @param error                  If non nil, filled in with error info if 
 *                                  there is an error.
 *
 *    @return true if the blame works.
 */
-(bool) blame: (NSString*) pathOrUrl
  pegRevision: (SFCRevision*) pegRevision
        start: (SFCRevision*) start
          end: (SFCRevision*) end
  diffOptions: (SFCDiffOptions*) diffOptions
ignoreMimeType: (bool) ignoreMimeType
includeMergedRevisions: (bool) includeMergedRevisions
   blameBlock: (SFCBlameBlock) blameBlock
        error: (NSError* __autoreleasing*) error;

/*!
 *    @brief List a directory and possibly its children.
 *
 *    @param pathOrUrl        Path or URL to list
 *    @param pegRevision      Peg revision to list at.
 *    @param revision         Actual revision to list at.
 *    @param depth            Controls how deep the list will go.
 *    @param fetchLocks       If true, include locks when reporting entries.
 *    @param includeExternals Also list externals if true
 *    @param listBlock        Block to execute on each list item found.
 *    @param error            If non nil, filled in with error info if
 *                            there is an error.
 *
 *    @return true if the list works OK.
 */
-(bool) list: (NSString*) pathOrUrl
 pegRevision: (SFCRevision*) pegRevision
    revision: (SFCRevision*) revision
       depth: (SFCDepth) depth
  fetchLocks: (bool) fetchLocks
includeExternals: (bool) includeExternals
   listBlock: (SFCListBlock) listBlock
       error: (NSError* __autoreleasing*) error;

/*!
 *    @brief List the properties of a target.
 *
 *    @param target       Target to get properties of
 *    @param pegRevision  Peg revision of the target.
 *    @param revision     Revision to get properties at
 *    @param depth        Depth filter for directory targets.
 *    @param changeLists  Changelist filter for the target.
 *    @param getInherited If true, get inherited propertie, otherwise, don't.
 *    @param receiver     Block that processes retrieved list items.
 *    @param error        If there is an error and this is non nil, it will be
 *                        filled in with error info.
 *
 *    @return true for success, false if something goes wrong.
 */
-(bool) propList: (NSString*) target
     pegRevision: (SFCRevision*) pegRevision
        revision: (SFCRevision*) revision
           depth: (SFCDepth) depth
     changeLists: (NSArray*) changeLists
       inherited: (bool) getInherited
       listBlock: (SFCPropListBlock) receiver
           error: (NSError* __autoreleasing*) error;

/*!
 *    @brief Copy a file or set of files to a new location.
 *
 *    @param sources            An array of @c SFCClientCopySource items to 
 *                              copy.  Must be either all URLS or all wc paths.
 *    @param destinationPath    Destination to copy to.  If there are 
 *                              multiple sources, this must be a directory.
 *    @param options            Copy options, copy as child, make parents, 
 *                              ignore externals.
 *    @param revisionProperties Revision properties to apply to the copy.
 *    @param commitBlock        If a commit is made, this will be called for 
 *                              each one.
 *    @param error              If there is an error and this is non nil, it 
 *                              will be filled in with error info.
 *
 *    @return true if it worked ok, false if not.
 */
-(bool) copySources: (NSArray*) sources
        destination: (NSString*) destinationPath
            options: (uint32_t) options
 revisionProperties: (NSDictionary*) revisionProperties
     committedBlock: (SFCCommittedBlock) commitBlock
              error: (NSError* __autoreleasing*) error;

/*!
 *    @brief Delete the given paths.
 *
 *    @param paths              Array of paths, either all WC paths or all
 *                              repo URLS
 *    @param force              If any of the local paths have changes, this 
 *                              forces them to be deleted anyway.
 *    @param keepLocal          Local copy of deleted items is kept.
 *    @param revisionProperties Custom revision properties or nil.
 *    @param commitBlock        If a commit is made, this will be called for
 *                              each one.
 *    @param error              If something goes wrong, this will contain an
 *                              error unless it is nil.
 *
 *    @return true if the delete was successful.
 */
-(bool) deletePaths: (NSArray*) paths
              force: (bool) force
          keepLocal: (bool) keepLocal
 revisionProperties: (NSDictionary*) revisionProperties
     committedBlock: (SFCCommittedBlock) commitBlock
              error: (NSError* __autoreleasing*) error;

/*!
 *    @brief Import a directory tree into the repository at url.
 *
 *    This imports the whole folder structure (but see depth) at the path.  .svn
 *    directories are ignored, so you can import a working copy.
 *
 *    @param path               Path to import.
 *    @param url                URL to import to. If the URL path is not 
 *                              complete in the repo, missing components are
 *                              created.
 *    @param depth              Controls how deep in the directory tree we go.
 *    @param options            Options, controls whether we import ignored files
 *                              whether we apply auto properties and whether we
 *                              ignore unknown node types.  See SFCImportOption
 *    @param revisionProperties Custom revision properties to apply.
 *    @param filterBlock        A block that can apply a filter to nodes to be 
 *                              imported.
 *    @param commitBlock        Called for each successful commit.
 *    @param error              If non nil and an error occurs, will be filled
 *                              in with error info.
 *
 *    @return true if the import was a success.
 */
-(bool) import: (NSString*) path
           url: (NSURL*) url
         depth: (SFCDepth) depth
       options: (uint32_t) options
revisionProperties: (NSDictionary*) revisionProperties
   filterBlock: (SFCImportFilter) filterBlock
committedBlock: (SFCCommittedBlock) commitBlock
         error: (NSError* __autoreleasing*) error;

/*!
 *    @brief Export a repo or wc path to the file system.
 *
 *    @param fromPathOrUrl  Path to export from.
 *    @param path           path to export to.
 *    @param pegRevision    Peg revision of node to export from.
 *    @param revision       Revision to export.
 *    @param options        Various options:  do we overwrite existing paths, 
 *                          ignore eternals or ignore svn keywords.  
 *                          See SFCExportOption
 *    @param depth          Depth filter for export.
 *    @param nativeEol      Allows you to override the eol marker.  Can be @"\\n",
 *                          @\\r\\n", @"\\r" or nil.  If nil, the default eol
 *                          for the paltform is used.
 *    @param resultRevision If not NULL, revision that is actually exported.
 *    @param error          If an error occurs, this will be filled in.
 *
 *    @return true for success, false for an error.
 */
-(bool) exportFrom: (NSString*) fromPathOrUrl
                to: (NSString*) path
       pegRevision: (SFCRevision*) pegRevision
          revision: (SFCRevision*) revision
           options: (uint32_t) options
             depth: (SFCDepth) depth
         nativeEol: (NSString*) nativeEol
    resultRevision: (SFCRevNum*) resultRevision
             error: (NSError* __autoreleasing*) error;

/*!
 *    @brief Perform a three way merge.
 *
 *    The differences between source1 @ revision1 and source2 @ revision 2 are
 *    applied to the given working copy path.
 *
 *    @param source1      URL or WC path for start of merge range.
 *    @param revision1    Revision for start of merge range.
 *    @param source2      URL or WC path for end of merge range.
 *    @param revision2    Revision for end of merge range.
 *    @param targetWcPath Target working copy to apply diffs to.
 *    @param depth        Depth filter for merge.
 *    @param options      Various merge options, see SFCMergeOption enum for 
 *                        details.
 *    @param mergeOptions Additional command line options for thr merge processes.
 *    @param error        If it goes wrong, an error will be put in here if it 
 *                        is not null.
 *
 *    @return true for sucess, false for failure.
 */
-(bool) mergeSource1: (NSString*) source1
           revision1: (SFCRevision*) revision1
             source2: (NSString*) source2
           revision2: (SFCRevision*) revision2
        targetWcPath: (NSString*) targetWcPath
               depth: (SFCDepth) depth
             options: (uint32_t) options
        mergeOptions: (NSArray*) mergeOptions
               error: (NSError* __autoreleasing*) error;

/*!
 *    @brief Move a set of paths to a new destination.
 *
 *    @param sources            WC paths or repo URLs to move.
 *    @param destination        Destination to move to, must be a directory if
 *                              there is more than one source.
 *    @param options            Move options.  See SFCMoveOption
 *    @param revisionProperties Revision properties for the commit.
 *    @param commitBlock        Called for each successful commit.
 *    @param error              If it goes wrong, an error will be put in here 
 *                              if it is not null.
 *
 *    @return true for success, false otherwise.
 */
-(bool) moveSources: (NSArray*) sources
        destination: (NSString*) destination
            options: (uint32_t) options
 revisionProperties: (NSDictionary*) revisionProperties
     committedBlock: (SFCCommittedBlock) commitBlock
              error: (NSError* __autoreleasing*) error;

/*!
 *    @brief PAtch a working copy with the given patch file.
 *
 *    @param patchFile   Patch file.
 *    @param workingCopy Location of working copy.
 *    @param options     Various options, see SFCPatchOption
 *    @param stripCount  specifies how many leading path components should be 
 *                       stripped from paths obtained from the patch.
 *    @param patchBlock  Filter block to run for each patched file.  This is 
 *                       callled before the file is patched.
 *    @param error       If an error occurs, put it here if non nil.
 *
 *    @return true for success, false if anything goes wrong.
 */
-(bool) patchFile: (NSString*) patchFile
      workingCopy: (NSString*) workingCopy
          options: (uint32_t) options
       stripCount: (unsigned int) stripCount
       patchBlock: (SFCPatchBlock) patchBlock
            error: (NSError* __autoreleasing*) error;

/*!
 *    @brief Relocate a wc from one URL to another.
 *
 *    This is used where the only thing that has changed is the repo URL, the
 *    wc still represents the same directory within the repo.
 *
 *    @param workingCopyPath Path to working copy.
 *    @param fromURI         Original URI
 *    @param toURI           Replacement URI
 *    @param ignoreExternals If true, don't relocate any externals.
 *    @param error           If an error occurs, this will be filled in if it is
 *                           not nil.
 *
 *    @return true for success, false otherwise
 */
-(bool) relocate: (NSString*) workingCopyPath
            from: (NSURL*) fromURI
              to: (NSURL*) toURI
 ignoreExternals: (bool) ignoreExternals
           error: (NSError* __autoreleasing*) error;

/*!
 *    @brief Resolve a conflict.
 *
 *    Performs automatic conflict resolution on the working copy path.  May use
 *    the client's conflictBlock to resolve the choice.
 *
 *    @param path           Path to resolve.
 *    @param depth          Depth filter on directory paths.
 *    @param conflictChoice Way to resolve the conflict, see SFCConflictChoice
 *    @param error          Error that will be filled in in the event of an 
 *                          error occurred (if it is not nil).
 *
 *    @return True for successful resolution.
 */
-(bool) resolve: (NSString*) path
          depth: (SFCDepth) depth
 conflictChoice: (SFCConflictChoice) conflictChoice
          error: (NSError* __autoreleasing*) error;

/*!
 *    @brief Remove the specified paths from the specified change lists.
 *
 *    @param paths       Array of working copy paths.
 *    @param depth       DEpth filter for paths that are directories.
 *    @param changeLists Change lists to remove stuff from.
 *    @param error       If an error occurs and this is non null, it will be 
 *                       filled in with error info.
 *
 *    @return true if successful, false if an error occurred.
 */
-(bool) removePaths: (NSArray*) paths
              depth: (SFCDepth) depth
    fromChangeLists: (NSArray*) changeLists
              error: (NSError* __autoreleasing*) error;

@end
